﻿using System;
using System.Collections.Generic;
using Verse;

namespace ARMIR.util {
    /// <summary>
    /// GUI帧管理工具类
    /// </summary>
    public class GuiTickUtil : GameComponent {
        public GuiTickUtil(Game game) : base() {
        }

        /// <summary>
        /// 行为结构体
        /// </summary>
        private struct DelayedAction {
            /// <summary>
            /// 这个方法的Id
            /// </summary>
            public string Id;

            /// <summary>
            /// 需要延迟多少tick
            /// </summary>
            public int TriggerTick;

            /// <summary>
            /// 委托需要做的操作
            /// </summary>
            public Action Action;
        }

        /// <summary>
        /// 需要延时执行tick的方法的集合
        /// </summary>
        private readonly List<DelayedAction> _delayedActionList = new List<DelayedAction>();

        /// <summary>
        /// 需要重复执行tick的方法集合
        /// </summary>
        private readonly List<DelayedAction> _repeatTickList = new List<DelayedAction>();

        /// <summary>
        /// 需要定时执行tick的行为集合
        /// </summary>
        private readonly List<DelayedAction> _timingTickList = new List<DelayedAction>();

        /// <summary>
        /// 设置每帧调用
        /// </summary>
        public override void GameComponentOnGUI() {
            base.GameComponentOnGUI();
            // 延迟方法
            DelayGuiTick();
            // 重复方法
            RepeatGuiTick();
            TimingGuiTick();
        }

        /// <summary>
        /// 需要定时tick执行的方法
        /// </summary>
        private void TimingGuiTick() {
            // 获取当前tick
            int currentTick = Find.TickManager.TicksGame;
            // 循环委托list
            for (int i = _timingTickList.Count - 1; i >= 0; i--) {
                // 执行动作
                _timingTickList[i].Action.Invoke();
                // 当前tick是否大于设定的tick
                if (currentTick >= _timingTickList[i].TriggerTick) {
                    // 删除已经执行的动作
                    _timingTickList.RemoveAt(i);
                }
            }
        }

        /// <summary>
        /// 重复执行方法
        /// </summary>
        private void RepeatGuiTick() {
            foreach (DelayedAction delayedAction in _repeatTickList) {
                // 执行方法
                delayedAction.Action.Invoke();
            }
        }

        /// <summary>
        /// 延迟tick执行方法
        /// </summary>
        private void DelayGuiTick() {
            // 获取当前tick
            int currentTick = Find.TickManager.TicksGame;
            // 循环委托list
            for (int i = _delayedActionList.Count - 1; i >= 0; i--) {
                // 当前tick是否大于设定的tick
                if (currentTick >= _delayedActionList[i].TriggerTick) {
                    // 执行动作
                    _delayedActionList[i].Action.Invoke();
                    // 删除已经执行的动作
                    _delayedActionList.RemoveAt(i);
                }
            }
        }

        /// <summary>
        /// tick时间管理器
        /// </summary>
        /// <param name="delayTicks">需要延迟多少tick</param>
        /// <param name="action">需要延迟的的方法</param>
        /// <param name="direction">
        /// 应该为延迟时间还是持续时间
        /// <list>
        /// <item>true: 延迟多少tick之后运行方法</item>
        /// <item>false: 执行多少tick之后停止方法</item>
        /// </list>
        /// </param>
        public void GuiTickTimeManager(int delayTicks, Action action, bool direction) {
            if (direction) {
                _delayedActionList.Add(new DelayedAction {
                        TriggerTick = Find.TickManager.TicksGame + delayTicks,
                        Action = action
                    }
                );
            }
            else {
                _timingTickList.Add(new DelayedAction {
                        TriggerTick = Find.TickManager.TicksGame + delayTicks,
                        Action = action
                    }
                );
            }
        }

        /// <summary>
        /// 添加重复执行的方法
        /// </summary>
        /// <param name="actions"></param>
        public string[] AddRepeatGuiTickAction(params Action[] actions) {
            string[] ids = new string[actions.Length];

            for (int i = 0; i < actions.Length; i++) {
                var guid = Guid.NewGuid().ToString();
                ids[i] = guid;
                _repeatTickList.Add(new DelayedAction {
                        // 设置这个行为的Id
                        Id = guid,
                        // 添加这个行为
                        Action = actions[i],
                    }
                );
            }

            return ids;
        }

        /// <summary>
        /// 移除重复执行的方法
        /// </summary>
        /// <param name="ids">方法的id列表</param>
        public void RemoveRepeatGuiTickAction(params string[] ids) {
            // 循环ide
            foreach (var id in ids) {
                _repeatTickList.RemoveAll(x => x.Id == id);
            }
        }
    }
}